package cn.hd01.web.controller;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.hd01.common.BaseConstant.IsBalance;
import cn.hd01.common.BaseConstant.RebateSummaryType;
import cn.hd01.common.PayType;
import cn.hd01.common.Payee;
import cn.hd01.common.PaymentType;
import cn.hd01.repository.entity.COrder;
import cn.hd01.repository.entity.COrderPayment;
import cn.hd01.repository.entity.Customer;
import cn.hd01.repository.entity.PayTypeReport;
import cn.hd01.repository.entity.RebateSummary;
import cn.hd01.service.COrderPaymentService;
import cn.hd01.service.COrderService;
import cn.hd01.service.CustomerService;
import cn.hd01.service.DictionaryService;
import cn.hd01.service.RebateSummaryService;
import cn.hd01.web.auth.Auth;

@Controller
@RequestMapping("/cOrderPayment")
@Auth
public class COrderPaymentController {
	
	@Autowired
	private COrderService cOrderService;
	
	@Autowired
	private COrderPaymentService cOrderPaymentService;
	
	@Autowired
	private DictionaryService dictionaryService;
	
	@Autowired
	private COrderService corderService;
	
	@Autowired
	private RebateSummaryService rebateSummaryService;
	
	@Resource
	private CustomerService customerService;
	
	
	@RequestMapping(method = RequestMethod.GET)
	public String index(Model m, HttpServletRequest request) {
		Integer orderId = StringUtils.isEmpty(request.getParameter("orderId")) ? null : Integer.valueOf(request.getParameter("orderId"));
		String name = StringUtils.isEmpty(request.getParameter("name")) ? null : String.valueOf(request.getParameter("name"));
		m.addAttribute("orderId", orderId);
		m.addAttribute("name", name);
		m.addAttribute("payTypeList", Arrays.asList(PayType.values()));
		m.addAttribute("payeeList", Arrays.asList(Payee.values()));
		m.addAttribute("paymentTypeList", Arrays.asList(PaymentType.values()));
		return "cOrderPayment";
	}

	@ResponseBody
	@RequestMapping(path = "/list", method = RequestMethod.GET)
	private Page<COrderPayment> find(COrderPayment c, @PageableDefault Pageable pageable, HttpServletRequest req) {
		List<COrderPayment> list = cOrderPaymentService.findByOrderId(c.getOrderId());
//		list.sort(new Comparator<COrderPayment>() {
//			public int compare(COrderPayment p1, COrderPayment p2) {  
//				if(Integer.valueOf(p1.getPayee()) > Integer.valueOf(p2.getPayee())){
//					return 1;
//				}else if(Integer.valueOf(p1.getPayee()) < Integer.valueOf(p2.getPayee())){
//					return -1;
//				}else{
//					if(p1.getPayTime().before(p2.getPayTime())){
//						return -1;
//					}else if(p1.getPayTime().after(p2.getPayTime())){
//						return 1;
//					}else{
//						return 0;
//					}
//				}
//			}  
//		}); 
		int hospitalCount = 1;
		int shopCount = 1;
		int count = 1;
		for(COrderPayment p : list){
			/*if(Payee.HOSPITAL.getCode().equals(p.getPayee())){
				p.setDesc("第" + hospitalCount++ + "次收款");
			}else{
				p.setDesc("第" + shopCount++ + "次收款");
			}*/
			p.setDesc("第" + count++ + "次收款");
		}
		
		Pageable pb = new PageRequest(1, CollectionUtils.isEmpty(list) ? 1 : list.size(), null);
		Page<COrderPayment> pageList = new PageImpl<COrderPayment>(list, pb, list.size());
		return pageList;
	}

	@ResponseBody
	@RequestMapping(path = "/delete/{id}", method = RequestMethod.GET)
	private void delete(@PathVariable("id") Integer id) {

		COrderPayment cOrderPayment = cOrderPaymentService.findOne(id);
		COrder order = corderService.findOne(cOrderPayment.getOrderId());

		BigDecimal distributorRebate = cOrderPayment.getAmount().subtract(cOrderPayment.getFeeAmount()).multiply(order.getDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
		updateRebate(order.getDistributorId(), distributorRebate.negate());

		if(order.getRecommDistributorId() != null && order.getRecommDistributorRebateRate() != null){
			BigDecimal recommDistributorRebate = cOrderPayment.getAmount().subtract(cOrderPayment.getFeeAmount()).multiply(order.getRecommDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
			updateRebate(order.getRecommDistributorId(), recommDistributorRebate.negate());
		}
		cOrderPaymentService.delete(id);
	}
	
	@ResponseBody
	@RequestMapping(path = "/save", method = RequestMethod.POST)
	private void save(COrderPayment cOrderPayment) {
		/*List<Dictionary> dictList = dictionaryService.findByType(DictionaryType.FEE_RATE);
		BigDecimal feeRate = BigDecimal.ZERO;
		String payType = cOrderPayment.getPayType();
		if(PayType.POS_QJ_1.getCode().equals(payType)){
			feeRate = new BigDecimal(dictList.get(0).getValue());
		}else if(PayType.POS_OM.getCode().equals(payType)){
			feeRate = new BigDecimal(dictList.get(1).getValue());
		}else if(PayType.WX.getCode().equals(payType)){
			feeRate = new BigDecimal(dictList.get(2).getValue());
		}else if(PayType.ALIPAY.getCode().equals(payType)){
			feeRate = new BigDecimal(dictList.get(3).getValue());
		}else if(PayType.SQB.getCode().equals(payType)){
			feeRate = new BigDecimal(dictList.get(4).getValue());
		}
		cOrderPayment.setFeeAmount(cOrderPayment.getAmount().multiply(feeRate));*/
		/*corderService.balanceOrder(cOrderPayment.getOrderId(), cOrderPayment);*/
		if(StringUtils.isEmpty(cOrderPayment.getIsBalance())){
			cOrderPayment.setIsBalance(IsBalance.BALANCE_WAIT);
		}
		COrder order = corderService.findOne(cOrderPayment.getOrderId());
		
		BigDecimal distributorRebate = cOrderPayment.getAmount().subtract(cOrderPayment.getFeeAmount()).multiply(order.getDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
		cOrderPayment.setDistributorRebate(distributorRebate);
		updateRebate(order.getDistributorId(), distributorRebate);
		
		if(order.getRecommDistributorId() != null && order.getRecommDistributorRebateRate() != null){
			BigDecimal recommDistributorRebate = cOrderPayment.getAmount().subtract(cOrderPayment.getFeeAmount()).multiply(order.getRecommDistributorRebateRate()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);
			cOrderPayment.setRecommDistributorRebate(recommDistributorRebate);
			updateRebate(order.getRecommDistributorId(), recommDistributorRebate);
			/*RebateSummary recommDisRebateSummary = rebateSummaryService.findByRefIdAndType(order.getRecommDistributorId(), RebateSummaryType.DISTRIBUTOR);
			Customer recommDistributor = customerService.findOne(order.getRecommDistributorId());
			if(recommDisRebateSummary == null){
				recommDisRebateSummary = new RebateSummary();
				recommDisRebateSummary.setAllRebate(recommDistributorRebate);
				recommDisRebateSummary.setAllWaitWithdrawRebate(recommDistributorRebate);
				recommDisRebateSummary.setAllWithdrawRebate(BigDecimal.ZERO);
				recommDisRebateSummary.setCreateTime(new Date());
				recommDisRebateSummary.setUpdateTime(new Date());
				recommDisRebateSummary.setRefId(order.getRecommDistributorId());
				recommDisRebateSummary.setName(recommDistributor.getName());
				recommDisRebateSummary.setType(RebateSummaryType.DISTRIBUTOR);
			}else{
				recommDisRebateSummary.setAllRebate(recommDisRebateSummary.getAllRebate().add(recommDistributorRebate));
				recommDisRebateSummary.setAllWaitWithdrawRebate(recommDisRebateSummary.getAllWaitWithdrawRebate().add(recommDistributorRebate));
			}
			rebateSummaryService.save(recommDisRebateSummary);*/
		}
		cOrderPaymentService.save(cOrderPayment);
	}
	
	private void updateRebate(Integer distributorId, BigDecimal rebate){
		Customer distributor = customerService.findOne(distributorId);
		RebateSummary disRebateSummary = rebateSummaryService.findByRefIdAndType(distributorId, RebateSummaryType.DISTRIBUTOR);
		if(disRebateSummary == null){
			disRebateSummary = new RebateSummary();
			disRebateSummary.setAllRebate(rebate);
			disRebateSummary.setAllWaitWithdrawRebate(rebate);
			disRebateSummary.setAllWithdrawRebate(BigDecimal.ZERO);
			disRebateSummary.setCreateTime(new Date());
			disRebateSummary.setUpdateTime(new Date());
			disRebateSummary.setRefId(distributorId);
			disRebateSummary.setName(distributor.getName());
			disRebateSummary.setType(RebateSummaryType.DISTRIBUTOR);
		}else{
			disRebateSummary.setAllRebate(disRebateSummary.getAllRebate().add(rebate));
			disRebateSummary.setAllWaitWithdrawRebate(disRebateSummary.getAllWaitWithdrawRebate().add(rebate));
		}
		rebateSummaryService.save(disRebateSummary);
	}
	
	@ResponseBody
	@RequestMapping(path = "/balance/{id}", method = RequestMethod.GET)
	private synchronized void balance(@PathVariable("id") Integer id) {
		COrderPayment cOrderPayment = cOrderPaymentService.findOne(id);
		if(!IsBalance.BALANCE_DOWN.equals(cOrderPayment.getIsBalance())){
			corderService.balanceOrder(cOrderPayment.getOrderId(), cOrderPayment);
			cOrderPayment.setIsBalance(IsBalance.BALANCE_DOWN);
			cOrderPaymentService.save(cOrderPayment);
			COrder order = corderService.findOne(cOrderPayment.getOrderId());
			order.setIsBalance(IsBalance.BALANCE_DOWN);
			corderService.save(order);
		}
	}
	
	@RequestMapping(path = "/payTypeReport", method = RequestMethod.GET)
	private String paymentReport(@PageableDefault Pageable pageable, HttpServletRequest req) {
		return "payTypeReport";
	}
	
	@ResponseBody
	@RequestMapping(path = "/payTypeReport/list", method = RequestMethod.GET)
	private Page<PayTypeReport> findPaymentReport(@PageableDefault Pageable pageable, PayTypeReport report) {
		Page<PayTypeReport> page = cOrderPaymentService.findPayTypeReport(pageable, report);
		/*List<PayTypeReport> content = page.getContent();
		if(!CollectionUtils.isEmpty(content)){
			for(PayTypeReport report : content){
				for(PayType type : PayType.values()){
					if(report.getPayType().equals(type.getCode())){
						report.setPayTypeName(type.getName());
						break;
					}
				}
			}
		}*/
		 
		return page;
	}

}
